package sync

import (
	"context"
	"fmt"
	"gitee.com/dreamwood/ez-go/ez"
)

func ListenToEvents() {
	//事件来源于ModelSync
	GetMS().ListenToInitNeed("Product", func(in *InitNeed) {
		//这里切忌，1.不要一次性发送过多的数据
		//2.不要发送过大的，比如包含富文本的
		//3实在不行可以发送接口地址，再自行获取数据
		model := struct {
			Id   int
			Name string
		}{
			103, "张三",
		}
		ez.Try(GetMS().FeedToInitEvent(in, model))
	})
	//事件来源于CRUD
	ez.Subscribe("crm.AfterProductCreate crm.AfterProductUpdate", func(v interface{}, ctx context.Context) {
		//model, ok := v.(models.Product)
		//if ok {
		//	errs.Try(MS.PubCrudUpdate("Product", model))
		//}
	})
}

// 主动发布
func Publish() {
	model := struct {
		Id   int
		Name string
	}{
		103, "张三",
	}
	//创建时发布
	ez.Try(GetMS().PubCrudCreate("SimpleUser", model))
	//更新时发布
	ez.Try(GetMS().PubCrudUpdate("SimpleUser", model))
	//删除时发布
	ez.Try(GetMS().PubCrudDelete("SimpleUser", model))
}

// PubInitNeed - 发布一个初始化的请求
// 主动通知初始化,订阅方主动索要初始化数据的行为。
// 使用场景如下：
// 当某个服务初始化时，需要初次拉取数据（或者因为某些原因需要重新拉取）时
// 订阅方主动发布PubInitNeed，告知发布方，我需要初始化数据，给爹送过来
// 发布方在SubInitNeed监听到这个事件，通过FeedNeeds（这里需要根据自己
// 的场景）自行实现，在FeedNeeds中，发布方应该调用FeedToInitEvent，把全部
// 需要传递的数据逐条发布过去，订阅方在SubInitFeed，会收到“数据来了，接
// 好了，孙贼！”，大量数据的涌来有可能让孙子崩溃，所以要么发布方做好数据分
// 批发送，要么订阅方自己做好分批缓冲操作。
// 事件流程如下：
// 1.发布方监听，执行SubInitNeed
// 2.订阅方监听，执行SubInitFeed
// 3.订阅方发起，执行PubInitNeed
// 4.发布方在SubInitNeed的回调中执行FeedToInitEvent
// 5.订阅方在SubInitFeed的回调中执行数据同步
func PubInitNeed() {
	//这个过程应该在接口中实现，以便于用户主动发起初始化请求
	ez.Try(GetMS().PubInitNeed("TargetPubName", "ModelName"))
}

// 创建监听
// 这个过程应该在init方法内完成，
// 并且在
func InitSub() {
	ez.Try(GetMS().SubInitFeed("I_AM_PUB_ER", "usage", func(data *ModelData) error {
		println(data.ModelName, data.Id, data.PubName, data.Crud)
		println(string(data.Data))
		return nil
	}))

	ez.Try(GetMS().SubCrud("I_AM_PUB_ER", "SimpleUser", "usage", func(data *ModelData) error {
		println("user sub", data.ModelName, data.Id, data.PubName, data.Crud)
		println(string(data.Data))
		return nil
	}))
}

func SubInitNeed() {
	//创建初始化监听,发布方被动响应的行为。
	//使用场景如下：
	//当某个服务初始化时，需要初次拉取数据（或者因为某些原因需要重新拉取）时
	//订阅方主动发布PubInitNeed，告知发布方，我需要初始化数据，给爹送过来
	//发布方在SubInitNeed监听到这个事件，通过FeedNeeds（这里需要根据自己
	//的场景）自行实现，在FeedNeeds中，发布方应该调用FeedToInitEvent，把全部
	//需要传递的数据逐条发布过去，订阅方在SubInitFeed，会收到“数据来了，接
	//好了，孙贼！”，大量数据的涌来有可能让孙子崩溃，所以要么发布方做好数据分
	//批发送，要么订阅方自己做好分批缓冲操作。
	//事件流程如下：
	//1.发布方监听，执行SubInitNeed
	//2.订阅方监听，执行SubInitFeed
	//3.订阅方发起，执行PubInitNeed
	//4.发布方在SubInitNeed的回调中执行FeedToInitEvent
	//5.订阅方在SubInitFeed的回调中执行数据同步
	ez.Try(MS.SubInitNeed(func(in *InitNeed) error {
		//通过event发布消息到内部
		ez.DispatchToMany(fmt.Sprintf("MsPub.SubInitNeed.%s", in.ModelName), in, context.TODO())
		return nil
	}))
}
